package com.zhou.org.controller;

import com.zhou.framework.aop.anotation.LogOption;
import com.zhou.framework.aop.enums.LogLevel;
import com.zhou.framework.dto.IntegerDto;
import com.zhou.framework.model.RS;
import com.zhou.framework.util.PageUtil;
import com.zhou.framework.util.SessionUtil;
import com.zhou.org.common.*;
import com.zhou.util.StringTool;
import com.zhou.org.dao.Right;
import com.zhou.org.dao.SysMenu;
import com.zhou.org.dto.*;
import com.zhou.org.service.ISysMenuService;
import com.zhou.org.service.MenuService;
import com.zhou.org.service.OrgService;
import com.zhou.org.service.RightService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author lang.zhou
 * @since 2022-08-23
 */
@Api(tags = "菜单管理接口")
@RestController
@RequestMapping("/sys/menu")
public class MenuController {
    @Autowired
    private ISysMenuService sysMenuService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private OrgService orgService;
    @Autowired
    private RightService rightService;

    @ApiOperation("菜单列表")
    @LogOption(LogLevel.QUERY)
    @GetMapping("/list")
    public Object getPageList(@Validated MenuQueryDto dto){
        List<SysMenu> list = sysMenuService.selectList(dto);
        return RS.data(list);
    }

    @ApiOperation("id查询菜单")
    @LogOption(value = LogLevel.QUERY,response = true)
    @RequestMapping("/get")
    public Object get(@RequestBody @Validated IntegerDto dto){

        return RS.data(menuService.getById(dto.getId()));
    }

    @ApiOperation("修改菜单")
    @LogOption(value = LogLevel.EDIT,response = true)
    @PostMapping("/save")
    public RS save(@RequestBody @Validated SysMenu dto){
        if(sysMenuService.checkMenuNameUnique(dto)){
            return RS.failed("菜单名称已存在");
        }
        if(Objects.equals(EnumConstant.YES_FRAME,dto.getIsFrame()) && !StringTool.isHttp(dto.getPath())){
            return RS.failed("地址必须以http(s)://开头");
        }
        if(sysMenuService.checkMenuCntByPerVal(dto)){
            return RS.failed("权限值已存在");
        }
        sysMenuService.saveMenu(dto);
        return RS.success();
    }

    @PostMapping("/listMenuRight")
    @ApiOperation("菜单授权详细列表")
    @LogOption(LogLevel.QUERY)
    public Object listMenuRight(@RequestBody RightQueryDto dto){
        PageUtil.offsetPage(dto);
        List<RightPageDto> rights = rightService.getRight(dto);
        return PageUtil.result(dto,rights);
    }

    @DeleteMapping("/delete")
    @ApiOperation("删除菜单")
    @LogOption(value = LogLevel.DELETE,response = true)
    public RS delete(@RequestParam Long menuId){
        int cnt = sysMenuService.getChildMenuCnt(menuId);
        if(cnt > 0){
            return RS.failed("删除失败，请先删除子菜单");
        }
        sysMenuService.deleteMenu(menuId);
        return RS.success();
    }

    /*@RequestMapping("/topMenu")
    public RS topMenu(){
        RS r = new RS();
        List<Menu> topMenu = menuService.getTopMenu();
        r.putData("menu",topMenu);
        return r;
    }
    @RequestMapping("/rightTree")
    public RS rightTree(){
        RS r = new RS();
        Integer orgId = SessionUtil.getCurrentUser().getOrgId();
        List<MenuTree> treeData = menuService.getRightMenuTree(orgId);
        r.putData("tree",treeData);
        return r;
    }*/
    @ApiOperation("菜单树")
    @LogOption(LogLevel.QUERY)
    @GetMapping("/tree")
    public RS tree(MenuQueryDto dto){
        List<SysMenu> tree = sysMenuService.selectList(dto);
        return RS.data(tree);
    }


    private void tree2List(List<SysMenu> tree,List<SysMenu> res){
        for (SysMenu mt : tree) {
            res.add(mt);
            if(!CollectionUtils.isEmpty(mt.getChildren())){
                tree2List(mt.getChildren(),res);
            }
        }
    }

    @ApiOperation("查询用户菜单权限")
    @LogOption(LogLevel.QUERY)
    @GetMapping("/rightData")
    public RS getMenuRightTree(@RequestParam Integer orgId){
        RS r = new RS();
        int currentOrgId = SessionUtil.getCurrentOrgId();
        List<SysMenu> tree = sysMenuService.selectMenuTree();

        List<SysMenu> menus = new ArrayList<>(100);
        tree2List(tree,menus);
        List<Integer> checkKeys = new ArrayList<>(20);

        if(orgId != null && orgId > 0){
            //是否为管理员用户
            boolean isAdmin = OrgUtil.adminOrgIds().contains(currentOrgId);
            Map<String,SysMenu> tmp = menus.stream().collect(Collectors.toMap(o -> String.valueOf(o.getMenuId()), o -> o, (v1, v2) -> v1,LinkedHashMap::new));

            List<Right> rights = RightUtil.getRight(RightKeyEnum.MENU,"YES",orgId);
            for(Right right : rights){
                SysMenu map = tmp.get(right.getObjectKey());
                if(map != null){
                    //自有权限
                    map.setSelf(orgId == right.getOrgId().intValue());
                    if(Objects.equals(right.getReject(),1)){
                        //拒绝权限
                        map.setChecked(false);
                        map.setClickNum(ClickNumEnum.REJECT.getEnumValue());
                    }else{
                        map.setChecked(true);
                        map.setClickNum(ClickNumEnum.CHECK.getEnumValue());
                    }

                }
            }
            //查询出当前用户的权限
            List<Right> rights2 = RightUtil.getRight(RightKeyEnum.MENU,"YES",currentOrgId);
            for(Right right : rights2){
                SysMenu map = tmp.get(right.getObjectKey());
                if(map != null){
                    //当前用户可以对这个菜单给别人进行授权
                    map.setDisabled(right.getReject()!=0);
                }
            }

            for(SysMenu map : menus){
                map.setDisabled(!isAdmin && map.getDisabled());
                if(map.getChecked()){
                    checkKeys.add(map.getMenuId().intValue());
                }
            }
        }
        r.putData("right",tree);
        return r;
    }
}

